home *** CD-ROM | disk | FTP | other *** search
- PAGE 59, 132
-
- TITLE MSTERM -- Terminal emulation module
-
- ; Update 9 Jan 86
-
- IF1
- %OUT >> Starting pass 1
- ELSE
- %OUT >> Starting pass 2
- ENDIF
-
- PUBLIC clscpt, defkey, cptfcb, inicpt, clscpi, telnet, Allow_blast
- PUBLIC dopar, shokey, prkey, Telnet2, Quit_emulator
-
- INCLUDE MsDefs.H
-
- DataS SEGMENT PUBLIC 'DataS'
-
- EXTRN flags:byte, trans:byte, DTA:BYTE, portval:word
- EXTRN Preload_buffer:BYTE, Preload_flag:BYTE, TakLev:BYTE, TakAdr:WORD
-
- EVEN
-
- temp dw 0
- temp1 dw ? ; Temporary storage.
- temp2 dw ? ; Temporary storage.
- ssp dw 0 ; Save SP in Telnet.
-
- SCNTLEN EQU 200 ; MAX # OF DEFINITIONS ONE can have
- defbsiz EQU 400 ; combined length of all definitions...
-
- scntab dw scntlen dup (?) ; scan codes redefined
- deftab dw scntlen dup (?) ; pointer to definition strings
- defptr dw defbuf ; pointer starts at beginning
- deflen dw defbsiz ; amt of space left in buffer
-
- targ termarg <0,1,80,24,cptchr,2dch,0,scntab,deftab,0,,parnon>
- crlf db cr,lf,'$'
- tmp db ?,'$'
-
- erms22 db '? No capture file open', Cr, Lf, '$'
- esctl db 'Control-$' ; [6]
-
- inthlp db ' ? Type this message',cr,lf
- db ' Space Return to terminal emulation',cr,lf
- db ' B Send a Break to the host',cr,lf
- db ' C Close the connection (return to command mode)',cr,lf
- db ' M Toggle Mode line (turn it on or off)',cr,lf
- db ' Q Quit logging to file',cr,lf
- db ' R Resume logging to file',cr,lf
- db ' S Show Status of the connection',cr,lf
- db ' 0 Send a NUL to the host',cr,lf
- db ' Typing the escape character will send it to the host'
- db 0
-
- intprm db ' Press an action key, or Space to continue$'
-
- sttmsg db ' Press any key to continue$'
-
- CPTFCB DB 25H DUP (?)
- CAPBUF DB 200 DUP (?)
- CAPBP DW ?
- CAPLFT DB ?
- Allow_blast DB 0 ; Flag that rapid-fire screen updates are OK
-
- defbuf db defbsiz dup (?)
- shkmsg db cr,lf,'Press key: $'
-
- DataS ENDS
-
- Code SEGMENT PUBLIC
-
- extrn comnd:near, outchr:near, stat0:near
- extrn escprt:near, clrbuf:near, term:near
- extrn cmblnk:near, locate:near, prtchr:near
- extrn beep:near, puthlp:near, Close_Screen:near
- extrn serini:near, sendbr:near, showkey:near
- EXTRN PutMod:NEAR, Simulate_port_char:NEAR
-
- ASSUME cs:Code, ds:DataS
-
- Quit_emulator DB ? ; Flag to quit back to command mode
-
- ; the show key command.
-
- shokey proc near
- mov ah,cmcfm ; confirm with carriage return
- call comnd
- jmp r ; uh oh...
- mov dx,offset shkmsg
- mov ah,prstr
- int dos ; print a prompt for it
- mov ax,offset targ ; give it terminal arg block.
- call showkey ; show them the key definition
- push ax
- push cx ; save results
- mov dx,offset crlf
- mov ah,prstr
- int dos
- pop cx
- pop ax
- call prkey ; print the buffer
- mov dx,offset crlf
- mov ah,prstr
- int dos
- jmp rskp ; and return
- shokey endp
-
- ; pass a string pointer in ax, length in cx.
- ; Prints the string, quoting any unprintables, except crlf.
-
- prkey proc near
- mov si,ax ; copy string ptr
- jcxz prke6 ; no string, stop here
- cld ; Forwards
- prke1: push cx ; save counter
- lodsb ; get a byte
- and al,7fH ; only consider low-order 7 bits.
- cmp al,' ' ; printable?
- jb prke2 ; no, print the hard way
- cmp al,7fH ; maybe a delete?
- jne prke4 ; no, can just put into string
- prke2: jcxz prke3 ; last char, can't be crlf
- cmp al,cr ; carriage return?
- jne prke3 ; no, go on
- cmp byte ptr [si],lf ; followed by linefeed?
- jne prke3
- mov ah,prstr
- mov dx,offset crlf
- int dos ; else just print crlf
- inc si ; skip over lf
- pop cx ; careful...
- dec cx
- push cx
- jmp short prke5
- prke3: push ax ; preserve the char
- mov ah,conout
- mov dl,'\'
- int dos ; print the quote character
- pop ax
- call proct ; print the octal byte
- jmp short prke5
- prke4: mov dl,al ; normal char, just print it
- mov ah,conout
- int dos
- prke5: pop cx ; restore count
- loop prke1
- prke6: ret ; and return
- prkey endp
-
- ; print the byte in al as an octal number
- proct proc near
- mov dl,al ; get the byte
- and dl,7h ; keep low-order byte
- mov cl,3
- shr al,cl ; shift to get next digit
- jz proc1 ; 0, no more to print
- push dx ; else save current digit
- call proct ; print rest
- pop dx
- proc1: mov ah,conout
- add dl,'0' ; make printable
- int dos
- ret
- proct endp
-
- ; This is the CONNECT command.
-
- TELNET PROC NEAR
- mov ah,cmcfm
- call comnd ; Get a confirm.
- jmp r ; Didn't get a confirm.
-
-
- ; Pre-confirmed entry to connect command ...
-
- Telnet2:
- mov cs:Quit_emulator, 0 ; We haven't quit yet
- mov Preload_flag, 0 ; There is no preloaded command yet
-
- mov al,targ.flgs ; get present flags
- and al,modoff ; this is only one we can keep around
- or al,havtt ; defaults (!)
- cmp flags.debug,0 ; debug mode?
- jz tel0 ; no, keep going
- or al,trnctl ; yes, show control chars
- tel0: cmp flags.vtflg,0 ; vt52 emulation?
- jz tel1
- or al,emheath
- tel1: mov bx,portval
- cmp [bx].ecoflg,0 ; echoing?
- jz tel2
- or al,lclecho
- tel2: mov targ.flgs,al ; store flags
- mov ah,flags.comflg
- mov targ.prt,ah ; Port 1 or 2
- mov ah,trans.escchr
- mov targ.escc,ah
- mov ah,[bx].parflg
- mov targ.parity,ah
- mov ax,[bx].baud
- mov targ.baudb,al
- mov ah,flags.capflg
- and ah,capt
- or targ.flgs,ah
- call serini ; init serial port
-
- tem: mov ax,offset targ ; Point to terminal arguments
- call term
- or targ.flgs,scrsam ; assume screen is the same.
-
- intchr: test cs:Quit_emulator, 1 ; Flag to quit completely?
- jnz intch0 ; Yes, don't need another char
-
- mov ah, ConInQ ; Quietly read a character
- int Dos
-
- mov ah,al
-
- cmp ah,' ' ; Is it a space?
- je tem ; Yes, go back to terminal emulation
-
- mov bh,ah ; Save the actual char.
- and ah,not ('a'-'A') ; Convert to upper case.
-
- cmp ah,'C' ; Is it close?
- jne intch1
-
- call Close_Screen ; Tell emulator to shut down
-
- intch0: call Check_for_preloaded_command ; Did host tell us to do something?
- jmp rskp ; and return
-
- intch1: cmp ah,'S' ; Is it status?
- jnz intch2
-
- call stat0 ; If so, call stat0.
- call puthlp ; put help on screen
- mov dx,offset sttmsg
- call PutMod ; Display a message in the mode line
-
- mov ah, ConInQ ; Quietly read a character
- int Dos
-
- and targ.flgs,not scrsam ; remember screen changed.
- jmp tem
-
- intch2: cmp ah,'B' ; Send a break? [20g]
- jne intch3 ; No. [20g]
- call sendbr ; Yes, so send a break. [20g]
- jmp tem ; And return. [20g]
- intch3: cmp ah,'M' ; mode line?
- jne intch4
- xor targ.flgs,modoff ; toggle mode line
- jmp tem ; and reconnect
-
- %OUT >> About half through source file
-
- intch4: cmp bh,'?' ; Is it help?
- jne intch5 ; If not, go to the next check.
- mov ax,offset inthlp ; If so, get the address of the help message.
- call puthlp ; write help msg
- mov dx,offset intprm
- call PutMod ; Display a message in the mode line
- and targ.flgs,not scrsam ; remember screen changed
- jmp intchr ; Get another char.
-
- intch5: cmp bh,trans.escchr ; Is it the escape char?
- jne intch7 ; No, try something else
-
- intch6: mov ah,al ; Escape char typed twice, send it out
- call outchr
- nop
- nop
- nop
- jmp tem ; Return, we are done here.
-
- intch7: cmp ah,'Q' ; maybe want to stop logging?
- jne intch8
-
- test targ.flgs,capt ; not capturing, can't do this
- jz intc10
- and targ.flgs,not capt ; stop capturing
- jmp tem ; and resume
-
- intch8: cmp ah,'R' ; maybe resume?
- jne intch9 ; no, keep going
-
- cmp flags.capflg,0 ; can we capture?
- jz intc10 ; no, forget it
-
- test targ.flgs,capt ; already capturing?
- jnz intc10 ; yes, can't toggle back on then
-
- or targ.flgs,capt ; else turn flag on
- jmp tem ; and resume
-
- intch9: cmp bh,'0' ; perhaps want a null (note original chr in bh)
- jne intc10
-
- mov ah,0
- call outchr
- nop
- nop
- nop
- jmp tem
-
- intc10: jmp tem ; Wrong key, just give up
-
- TELNET ENDP
-
-
- ; Check for preloaded command ... if there is one, set it up as a macro,
- ; turning single commas into Cr's, and pushing the result onto the TAKE stack
-
- Check_for_preloaded_command PROC
-
- cmp Preload_flag, 0 ; Is there a preloaded command to be done?
- je CPC_ret ; No
-
- cld ; Forwards
- inc TakLev ; Bump take level
- add takadr, SIZE takinfo ; Address new take frame
- mov bx, TakAdr ; Get TAKE frame addr into bx
- mov BYTE PTR [bx].TakFcb, 0FFh ; Mark as a macro
- mov si, OFFSET Preload_buffer ; Pointer to where preloaded command is
- lea di, [bx].TakBuf ; Put it in the TAKE buffer
- sub cx, cx ; Clear counter
-
- CPC_1: lodsb ; Get a byte
- cmp al, ',' ; Comma?
- jne CPC_3 ; No
-
- mov ah, BYTE PTR [si] ; Peek at the next char
- cmp ah, ',' ; Is it also a comma?
- je CPC_2
-
- mov al, Cr ; Convert single comma to a Cr
- jmp SHORT CPC_3 ; Store it
-
- CPC_2: inc si ; Skip over the "peeked" second comma
-
- CPC_3: stosb ; Deposit char
- inc cx ; Count this char
- or al, al ; Hit end?
- jne CPC_1 ; Yes
-
- dec cx ; Uncount the null at the end
- lea ax, [bx].takbuf ; Pick up ptr to start of TAKE buffer
- mov [bx].takptr, ax ; Init buffer ptr
- mov [bx].takchl, cl ; Chars remaining
- mov [bx].takcnt, cx ; and all chars
- mov [bx].takcnt+2, 0 ; Clear high order half
-
- CPC_ret:
- ret ; Done here
-
- Check_for_preloaded_command ENDP
-
- ; Set parity for character in Register AL.
-
- dopar: push bx
- mov bx,portval
- cmp [bx].parflg,parnon ; No parity? [10 start]
- je parret ; Just return
- cmp [bx].parflg,parevn ; Even parity?
- jne dopar0
- and al,07FH ; Strip parity.
- jpe parret ; Already even, leave it.
- or al,080H ; Make it even parity.
- jmp parret
-
- dopar0: cmp [bx].parflg,parmrk ; Mark parity?
- jne dopar1
- or al,080H ; Turn on the parity bit.
- jmp parret
-
- dopar1: cmp [bx].parflg,parodd ; Odd parity?
- jne dopar2
- and al,07FH ; Strip parity.
- jpo parret ; Already odd, leave it.
- or al,080H ; Make it odd parity.
- jmp parret
-
- dopar2: and al,07FH ; Space parity - turn off parity bit.
-
- parret: pop bx
- ret ; [10 end]
-
- inicpt proc near
- mov capbp,offset capbuf
- mov caplft,128 ; init buffer ptr & chrs left
- ret ; and return
- inicpt endp
-
-
- ; Capture routine, char in al
-
- CptChr PROC
- push di
- mov di,capbp
- mov byte ptr [di],al
- inc di
- mov capbp,di ; restore pointer
- pop di
- dec caplft ; decrement chars remaining
- jnz cptch1 ; more room, forget this part
-
- call cptdmp ; dump the info
- call inicpt ; re-init ptrs.
-
- cptch1: ret ; and return
-
- cptchr ENDP
-
- cptdmp proc near ; empty the capture buffer
- push ax
- push dx
- mov ah,setdma
- mov dx,offset capbuf ; the capture routine buffer
- int dos
- mov ah,writef
- mov dx,offset cptfcb
- int dos ; write out the block
-
- ;*** must be fixed... check error returns, disable capturing,
- ;*** figure out how to put dma address back
-
- mov dx,offset DTA
- mov ah,setdma
- int dos ; put dma back
-
- pop dx
- pop ax
- ret
-
- cptdmp ENDP
-
- clscpt PROC
-
- mov ah,cmcfm
- call comnd
- jmp r
-
- test flags.capflg,0FFH ; doing capture
- jnz clscpi ; yes, go ahead
-
- mov dx,offset erms22
- mov ah,prstr
- int dos
-
- jmp rskp
-
- clscpi: mov al,'Z'-64 ; control-z for eof...
- call cptchr ; output to file
- mov al,caplft
- cmp al,128 ; is buffer empty?
- je clscp2 ; yes, forget this stuff
- call cptdmp ; dump buffer (preserves registers)
- clscp2: mov ah,0
- sub word ptr cptfcb+16,ax ; subtract remaining from low filsize
- sbb word ptr cptfcb+18,0 ; and from high size (with borrow)
- mov ah,closf
- mov dx,offset cptfcb
- int dos ; close up file
- mov flags.capflg,0 ; no longer capturing...
- jmp rskp ; and return
-
- clscpt ENDP
-
- ; enter with ax/scan code to define, si/ pointer to definition, cx/ length
- ; of definition. Defines it in definition table.
- ;*** somewhere should check for overflow etc of defbuf, and of scntab
- defkey proc near
- push ax ; save scan code
- cld ; Forwards
- mov ax,ds
- mov es,ax ; address data segment
- mov di,defptr ; this is where the def gets built
- inc di ; leave a byte for length
- defk1: lodsb ; get a byte from the source
- cmp al,'\' ; escape?
- jne defk2 ; no, just deposit him
- dec cx ; count available is one less
- call trnesc ; translate the escape sequence
- inc cx ; account for '\' (loop will decrement again).
- defk2: stosb ; drop off character
- loop defk1 ; and keep going while we have more
- mov ax,di ; get ptr to end
- dec ax ; back up pointer to end
- mov si,defptr ; pick up old ptr value
- sub ax,si ; this is actual length used
- mov byte ptr [si],al ; fill in length of entry
- mov defptr,di ; this is next free byte
- ; definition address is in si
- pop ax ; recover scan code
- mov cx,targ.klen ; length of scan table
- jcxz defk4 ; not there, just go add it
- mov di,offset scntab ; the scan code table
- repne scasw ; look for this one
- jne defk4 ; not defined already
- sub di,offset scntab + 2 ; compute index into table
- mov deftab[di],si ; fill in address
- ret ; and return
-
- defk4: mov di,targ.klen ; get length again
- inc di
- cmp di,scntlen
- ja defk5 ;** ignore def if over size
-
- mov targ.klen,di ; update length
- shl di,1 ; double for word index
- mov scntab[di-2],ax ; put scan code into table
- mov deftab[di-2],si ; and fill in definition
-
- defk5: ret ; that's it
-
- defkey ENDP
-
-
- ; enter with si/ source pointer, cx/ count
- ; converts an escape sequence, updates all pointers
-
- trnesc proc
- push bx
- push dx ; preserve these
- mov al,0 ; this is current accumulation
- jcxz trnes2 ; empty string, forget it
- mov bl,3 ; this is max # of digits to use
- mov bh,8 ; this is radix
-
- trnes1: mov dl,[si]
- cmp dl,'0'
- jb trnes2 ; out of range, stop here
-
- cmp dl,'7'
- ja trnes2
-
- inc si ; accept character
- sub dl,'0' ; convert to binary
- mul bh ; shift accumulation
- add al,dl ; add to accumulation
- dec bl ; decrement digit counter
- loopnz trnes1 ; and keep trying
-
- trnes2: pop dx
- pop bx
- ret ; and return
-
- trnesc endp
-
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr.
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ; ret
- RSKP ENDP
-
- ; Jumping here is the same as a ret.
-
- R PROC NEAR
- ret
- R ENDP
-
- Code ENDS
-
- END
-